﻿using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace PrimitiveEngine.Primitives
{
    public class PERectangle : PEPrimitive
    {
        public float Width;
        public float Height;
        public float BorderWidth;
        public Color BorderColor;

        public override int PrimitiveCount { get { return primitiveCount; } }

        private static Vector3[] tempArray1 = new Vector3[4];
        private static Vector3[] tempArray2 = new Vector3[4];

        private int primitiveCount = 0;

        private static Vector3[] rectangleIdentityCoords = new Vector3[] { 
            new Vector3(0.5f, 0.5f, 0f),
            new Vector3(0.5f, -0.5f, 0f),
            new Vector3(-0.5f, -0.5f, 0f),
            new Vector3(-0.5f, 0.5f, 0f),
        };

        internal static Vector2[] texCoords = new Vector2[] { new Vector2(0, 0), new Vector2(1, 0), new Vector2(0, 1), new Vector2(1, 1) };

        public PERectangle()
        {
            Type = PEPrimitiveType.Rectangle;
        }

        public PERectangle(float width, float height)
        {
            Type = PEPrimitiveType.Rectangle;
            Width = width;
            Height = height;
            BorderColor = Color.White;
            BorderWidth = 1.0f;
            BorderColor = Color.Black;
        }

        public PERectangle(float width, float height, float layer, Color color)
        {
            Type = PEPrimitiveType.Rectangle;
            Width = width;
            Height = height;
            Layer = layer;
            FillColor = color;
            IsFilled = true;
            BorderWidth = 1.0f;
            BorderColor = Color.Black;
        }

        public override bool Intersection(PEPrimitive primitive)
        {
            throw new NotImplementedException();
        }

        public override bool Inside(Microsoft.Xna.Framework.Vector2 point)
        {
            throw new NotImplementedException();
        }

        public override void CreateUV()
        {
            throw new NotImplementedException();
        }

        public override void Draw(ref VertexPositionColorTexture[] vertices, ref int vertexIndex, ref short[] indices, ref int indiceIndex)
        {
            int tempIndex = vertexIndex;
            primitiveCount = 0;

            Matrix mat = Matrix.CreateScale(Width - BorderWidth * 2, Height - BorderWidth * 2, 1f) * Matrix.CreateRotationZ(Rotation) * Matrix.CreateTranslation(new Vector3(Position, -Layer));

            Vector3.Transform(rectangleIdentityCoords, ref mat, tempArray2);

            if (IsFilled)
            {
                vertices[vertexIndex].Position = tempArray2[0];
                vertices[vertexIndex].Color = FillColor;
                vertices[vertexIndex].TextureCoordinate = texCoords[0];
                vertexIndex++;
                vertices[vertexIndex].Position = tempArray2[1];
                vertices[vertexIndex].Color = FillColor;
                vertices[vertexIndex].TextureCoordinate = texCoords[1];
                vertexIndex++;
                vertices[vertexIndex].Position = tempArray2[2];
                vertices[vertexIndex].Color = FillColor;
                vertices[vertexIndex].TextureCoordinate = texCoords[2];
                vertexIndex++;
                vertices[vertexIndex].Position = tempArray2[3];
                vertices[vertexIndex].Color = FillColor;
                vertices[vertexIndex].TextureCoordinate = texCoords[3];
                vertexIndex++;

                // create the indices
                indices[indiceIndex + 0] = (short)(tempIndex + 2);
                indices[indiceIndex + 1] = (short)(tempIndex + 1);
                indices[indiceIndex + 2] = (short)(tempIndex + 0);
                indices[indiceIndex + 3] = (short)(tempIndex + 3);
                indices[indiceIndex + 4] = (short)(tempIndex + 2);
                indices[indiceIndex + 5] = (short)(tempIndex + 0);
                indiceIndex += 6;

                primitiveCount += 2;

                // reset index
                tempIndex = vertexIndex;
            }

            if (BorderWidth > 0)
            {
                mat = Matrix.CreateScale(Width, Height, 1f) * Matrix.CreateRotationZ(Rotation) * Matrix.CreateTranslation(new Vector3(Position, -Layer));

                Vector3.Transform(rectangleIdentityCoords, ref mat, tempArray1);

                // scale the normal by half the lines width and translate to the start and end of the line
                vertices[vertexIndex].Position = tempArray1[0];
                vertices[vertexIndex].Color = BorderColor;
                vertices[vertexIndex].TextureCoordinate = texCoords[0];
                vertexIndex++;
                vertices[vertexIndex].Position = tempArray1[1];
                vertices[vertexIndex].Color = BorderColor;
                vertices[vertexIndex].TextureCoordinate = texCoords[1];
                vertexIndex++;
                vertices[vertexIndex].Position = tempArray1[2];
                vertices[vertexIndex].Color = BorderColor;
                vertices[vertexIndex].TextureCoordinate = texCoords[2];
                vertexIndex++;
                vertices[vertexIndex].Position = tempArray1[3];
                vertices[vertexIndex].Color = BorderColor;
                vertices[vertexIndex].TextureCoordinate = texCoords[3];
                vertexIndex++;
                vertices[vertexIndex].Position = tempArray2[0];
                vertices[vertexIndex].Color = BorderColor;
                vertices[vertexIndex].TextureCoordinate = texCoords[0];
                vertexIndex++;
                vertices[vertexIndex].Position = tempArray2[1];
                vertices[vertexIndex].Color = BorderColor;
                vertices[vertexIndex].TextureCoordinate = texCoords[1];
                vertexIndex++;
                vertices[vertexIndex].Position = tempArray2[2];
                vertices[vertexIndex].Color = BorderColor;
                vertices[vertexIndex].TextureCoordinate = texCoords[2];
                vertexIndex++;
                vertices[vertexIndex].Position = tempArray2[3];
                vertices[vertexIndex].Color = BorderColor;
                vertices[vertexIndex].TextureCoordinate = texCoords[3];
                vertexIndex++;

                indices[indiceIndex + 0] = (short)(tempIndex + 0);
                indices[indiceIndex + 1] = (short)(tempIndex + 1);
                indices[indiceIndex + 2] = (short)(tempIndex + 5);
                indices[indiceIndex + 3] = (short)(tempIndex + 0);
                indices[indiceIndex + 4] = (short)(tempIndex + 5);
                indices[indiceIndex + 5] = (short)(tempIndex + 4);
                indiceIndex += 6;

                indices[indiceIndex + 0] = (short)(tempIndex + 1);
                indices[indiceIndex + 1] = (short)(tempIndex + 2);
                indices[indiceIndex + 2] = (short)(tempIndex + 5);
                indices[indiceIndex + 3] = (short)(tempIndex + 2);
                indices[indiceIndex + 4] = (short)(tempIndex + 6);
                indices[indiceIndex + 5] = (short)(tempIndex + 5);
                indiceIndex += 6;

                indices[indiceIndex + 0] = (short)(tempIndex + 2);
                indices[indiceIndex + 1] = (short)(tempIndex + 7);
                indices[indiceIndex + 2] = (short)(tempIndex + 3);
                indices[indiceIndex + 3] = (short)(tempIndex + 2);
                indices[indiceIndex + 4] = (short)(tempIndex + 6);
                indices[indiceIndex + 5] = (short)(tempIndex + 7);
                indiceIndex += 6;

                indices[indiceIndex + 0] = (short)(tempIndex + 7);
                indices[indiceIndex + 1] = (short)(tempIndex + 3);
                indices[indiceIndex + 2] = (short)(tempIndex + 0);
                indices[indiceIndex + 3] = (short)(tempIndex + 0);
                indices[indiceIndex + 4] = (short)(tempIndex + 4);
                indices[indiceIndex + 5] = (short)(tempIndex + 7);
                indiceIndex += 6;

                primitiveCount += 8;
            }
        }
    }
}
